package com.brush.app.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.brush.app.domain.AppAd;
import com.brush.app.domain.AppSubject;
import com.brush.app.domain.req.Subject.add.AppSubjectAddReq;
import com.brush.app.domain.req.Subject.edit.AppSubjectEditReq;
import com.brush.app.domain.req.Subject.query.AppSubjectQueryReq;
import com.brush.app.domain.resp.Ad.AppAdResp;
import com.brush.app.domain.resp.Subject.AppSubjectResp;
import com.brush.app.domain.resp.Subject.AppSubjectTreeResp;
import com.brush.app.service.AppSubjectService;
import com.brush.app.mapper.AppSubjectMapper;
import com.brush.common.exception.database.PrimaryKeyException;
import com.brush.common.exception.database.RecordNotFoundException;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

/**
* @author ckq
* @description 针对表【app_subject(学科表)】的数据库操作Service实现
* @createDate 2024-11-01 00:32:38
*/
@Service
public class AppSubjectServiceImpl extends ServiceImpl<AppSubjectMapper, AppSubject>
    implements AppSubjectService{

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public PageInfo<AppSubjectResp> paginationQuery(AppSubjectQueryReq req) {
        return PageHelper.startPage(req.getPageNum(),req.getPageSize()).doSelectPageInfo(()->{
            this.baseMapper.paginationQuery(req);
        });
    }

    @Override
    public AppSubjectResp findById(Long id) {
        AppSubjectResp db = this.baseMapper.findById(id);
        if (Objects.isNull(db)) {
            throw new RecordNotFoundException();
        }
        return db;
    }

    @Override
    public boolean add(AppSubjectAddReq req) {
        //检验学科名name是否存在
        if (this.baseMapper.exists(new LambdaQueryWrapper<AppSubject>().eq(AppSubject::getName, req.getName()))) {
            throw new RecordNotFoundException();
        }
        AppSubject newEntity = new AppSubject();
        BeanUtils.copyProperties(req, newEntity);
        return this.save(newEntity);

    }

    @Override
    public boolean edit(AppSubjectEditReq req) {
        AppSubject appSubject = this.getById(req.getId());
        if (Objects.isNull(appSubject)){
            throw new RecordNotFoundException();
        }
        appSubject.setId(req.getId());
        appSubject.setName(req.getName());
        appSubject.setRemark(req.getRemark());
        appSubject.setImagePath(req.getImagePath());
        appSubject.setStatus(req.getStatus());

        return this.updateById(appSubject);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean deleteById(Long[] ids) {
        final AppSubjectServiceImpl appSubjectService = this;
        if (Objects.isNull(ids) || ids.length == 0) {
            throw new PrimaryKeyException();
        }
        this.redisTemplate.execute(new SessionCallback<Void>() {
            @Override
            public Void execute(RedisOperations operations) throws DataAccessException {
                // 开启redis事务
                operations.multi();

                // 循环删除，因为数据量不大, 时间复杂度O(n), 事务问题
                try {
                    for (Long id : ids) {
                        AppSubject db = appSubjectService.getById(id);
                        if (Objects.nonNull(db)) {
                            //删除数据库中的值
                            appSubjectService.removeById(id);
                            //移出缓存中的值
                            String redisKey = " "+db.getId();
                            operations.delete(redisKey);
                        }
                    }
                    // 提交redis事务
                    operations.exec();

                } catch (Exception e) {
                    operations.discard();
                    throw e;
                }
                return null;
            }
        });
        return true;
    }

    @Override
    public List<AppSubjectTreeResp> getAllSubject() {
        List<AppSubjectTreeResp> allSubject=this.baseMapper.getAllSubject();
        return allSubject;
    }
}




